package com.changgou.seckill.service.impl;

import com.changgou.common.pojo.SeckillStatus;
import com.changgou.seckill.dao.SeckillGoodsMapper;
import com.changgou.seckill.dao.SeckillOrderMapper;
import com.changgou.seckill.pojo.SeckillGoods;
import com.changgou.seckill.pojo.SeckillOrder;
import com.changgou.seckill.service.SeckillOrderService;
import com.changgou.seckill.task.MuilThreadingCreateOrder;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

/** ** @Author:shenkunlin @Description:SeckillOrder业务层接口实现类 @Date 2019/6/14 0:16 *** */
@Service
public class SeckillOrderServiceImpl implements SeckillOrderService {

  @Autowired private SeckillOrderMapper seckillOrderMapper;
  @Autowired private SeckillGoodsMapper seckillGoodsMapper;
  @Autowired private RedisTemplate redisTemplate;
  @Autowired private MuilThreadingCreateOrder muilThreadingCreateOrder;

  /**
   * 删除订单
   * @param username
   */
  @Override
  public void deleteOrder(String username) {
    //删除redi中的订单的数据
    redisTemplate.boundHashOps("SeckillOrder").delete(username);
    // 查询订单的信息，从用户的排队信息中
    SeckillStatus seckillStatus = (SeckillStatus) redisTemplate.boundHashOps("UserQueueStatus").get(username);
    //删除用户的排队信息
    clearUserQueue(username);
    // 回滚库存，redi递减，redis不一定有商品
    String namespace="SeckillGoods_"+seckillStatus.getTime();
    // 获得商品的信心
    SeckillGoods seckillGoods = (SeckillGoods) redisTemplate.boundHashOps(namespace).get(seckillStatus.getGoodsId());
    // 判断商品是否为空
    if (seckillGoods==null){
      //数据库的商品数量增加1
      SeckillGoods seckillGoods1 = seckillGoodsMapper.selectByPrimaryKey(seckillStatus.getGoodsId());
      seckillGoods1.setStockCount(1);
      seckillGoodsMapper.updateByPrimaryKeySelective(seckillGoods1);
    }else {
      // 从redis中查询出来的商品库存加1
      seckillGoods.setStockCount(seckillGoods.getStockCount()+1);
    }
    // 更新商品的redis
    redisTemplate.boundHashOps(namespace).put(seckillStatus.getGoodsId(),seckillGoods);
    // 更新队列的商品数量
    redisTemplate.boundListOps("SeckillGoodsCountList_"+seckillStatus.getGoodsId()).leftPush(seckillStatus.getGoodsId());

  }

  /**
   * 秒杀订单的修改
   *
   * @param username 用户名
   * @param transactionId 交易流水号
   */
  @Override
  public void updatePayStatus(String username, String transactionId) {
    // redisTemplate.boundHashOps("SeckillOrder").put(username,seckillOrder);
    //    查询订单，因为订单时存放到redis中的
    SeckillOrder seckillOrder = (SeckillOrder) redisTemplate.boundHashOps("SeckillOrder").get(username);
    if(seckillOrder!=null){
        // 修改订单的状态
      seckillOrder.setStatus("1");
      seckillOrder.setTransactionId(transactionId);
      seckillOrder.setPayTime(new Date());
      // 更新订单的信息
      seckillOrderMapper.insertSelective(seckillOrder);
      // 删除redis中该用户的订单的信息
      redisTemplate.boundHashOps("SeckillOrder").delete(username);
      //删除用户的排队的信息
      clearUserQueue(username);
    }
  }
  /**
   * 清理用户的信息(设置超时的时间)
   * @param username
   */
  public  void clearUserQueue(String username){
    // 清理用户的排队次数
    redisTemplate.boundHashOps("userQueueCount").delete(username);
    // 清理用户排队的信息
    redisTemplate.boundHashOps("UserQueueStatus").delete(username);
  }
  /**
   * 抢单状态查询
   *
   * @param username
   * @return
   */
  @Override
  public SeckillStatus userQueue(String username) {

    return (SeckillStatus) redisTemplate.boundHashOps("UserQueueStatus").get(username);
  }

  /**
   * SeckillOrder条件+分页查询
   *
   * @param seckillOrder 查询条件
   * @param page 页码
   * @param size 页大小
   * @return 分页结果
   */
  @Override
  public PageInfo<SeckillOrder> findPage(SeckillOrder seckillOrder, int page, int size) {
    // 分页
    PageHelper.startPage(page, size);
    // 搜索条件构建
    Example example = createExample(seckillOrder);
    // 执行搜索
    return new PageInfo<SeckillOrder>(seckillOrderMapper.selectByExample(example));
  }

  /**
   * SeckillOrder分页查询
   *
   * @param page
   * @param size
   * @return
   */
  @Override
  public PageInfo<SeckillOrder> findPage(int page, int size) {
    // 静态分页
    PageHelper.startPage(page, size);
    // 分页查询
    return new PageInfo<SeckillOrder>(seckillOrderMapper.selectAll());
  }

  /**
   * SeckillOrder条件查询
   *paidua
   * @param seckillOrder
   * @return
   */
  @Override
  public List<SeckillOrder> findList(SeckillOrder seckillOrder) {
    // 构建查询条件
    Example example = createExample(seckillOrder);
    // 根据构建的条件查询数据
    return seckillOrderMapper.selectByExample(example);
  }

  /**
   * SeckillOrder构建查询对象
   *
   * @param seckillOrder
   * @return
   */
  public Example createExample(SeckillOrder seckillOrder) {
    Example example = new Example(SeckillOrder.class);
    Example.Criteria criteria = example.createCriteria();
    if (seckillOrder != null) {
      // 主键
      if (!StringUtils.isEmpty(seckillOrder.getId())) {
        criteria.andEqualTo("id", seckillOrder.getId());
      }
      // 秒杀商品ID
      if (!StringUtils.isEmpty(seckillOrder.getSeckillId())) {
        criteria.andEqualTo("seckillId", seckillOrder.getSeckillId());
      }
      // 支付金额
      if (!StringUtils.isEmpty(seckillOrder.getMoney())) {
        criteria.andEqualTo("money", seckillOrder.getMoney());
      }
      // 用户
      if (!StringUtils.isEmpty(seckillOrder.getUserId())) {
        criteria.andEqualTo("userId", seckillOrder.getUserId());
      }
      // 商家
      if (!StringUtils.isEmpty(seckillOrder.getSellerId())) {
        criteria.andEqualTo("sellerId", seckillOrder.getSellerId());
      }
      // 创建时间
      if (!StringUtils.isEmpty(seckillOrder.getCreateTime())) {
        criteria.andEqualTo("createTime", seckillOrder.getCreateTime());
      }
      // 支付时间
      if (!StringUtils.isEmpty(seckillOrder.getPayTime())) {
        criteria.andEqualTo("payTime", seckillOrder.getPayTime());
      }
      // 状态，0未支付，1已支付
      if (!StringUtils.isEmpty(seckillOrder.getStatus())) {
        criteria.andEqualTo("status", seckillOrder.getStatus());
      }
      // 收货人地址
      if (!StringUtils.isEmpty(seckillOrder.getReceiverAddress())) {
        criteria.andEqualTo("receiverAddress", seckillOrder.getReceiverAddress());
      }
      // 收货人电话
      if (!StringUtils.isEmpty(seckillOrder.getReceiverMobile())) {
        criteria.andEqualTo("receiverMobile", seckillOrder.getReceiverMobile());
      }
      // 收货人
      if (!StringUtils.isEmpty(seckillOrder.getReceiver())) {
        criteria.andEqualTo("receiver", seckillOrder.getReceiver());
      }
      // 交易流水
      if (!StringUtils.isEmpty(seckillOrder.getTransactionId())) {
        criteria.andEqualTo("transactionId", seckillOrder.getTransactionId());
      }
    }
    return example;
  }

  /**
   * 删除
   *
   * @param id
   */
  @Override
  public void delete(Long id) {
    seckillOrderMapper.deleteByPrimaryKey(id);
  }

  /**
   * 修改SeckillOrder
   *
   * @param seckillOrder
   */
  @Override
  public void update(SeckillOrder seckillOrder) {
    seckillOrderMapper.updateByPrimaryKey(seckillOrder);
  }

  /**
   * 秒杀下单
   *
   * @param time 秒杀商品的时间段
   * @param id 秒杀商品id
   * @param username 秒杀商品的username
   * @return
   */
  @Override
  public boolean add(String time, long id, String username) {
    /** 记录用户的排队的次数 1. key 2.自增的值 从1开始自增 使用到的知识点就是redis是单线程的 */
    long userQueueCount = redisTemplate.boundHashOps("userQueueCount").increment(username, 1);
    if (userQueueCount > 1) {
        throw new RuntimeException("100");
    }
    SeckillStatus seckillStatus = new SeckillStatus(username, new Date(), 1, id, time);
    // list是队列类型有序的 （左存入，右取）
    redisTemplate.boundListOps("SeckillOrderQueue").leftPush(seckillStatus);
    // 存储用户排队的信息
    redisTemplate.boundHashOps("UserQueueStatus").put(username, seckillStatus);
    // 异步执行
    muilThreadingCreateOrder.createOrder();
    return true;
  }

  /**
   * 根据ID查询SeckillOrder
   *
   * @param id
   * @return
   */
  @Override
  public SeckillOrder findById(Long id) {
    return seckillOrderMapper.selectByPrimaryKey(id);
  }

  /**
   * 查询SeckillOrder全部数据
   *
   * @return
   */
  @Override
  public List<SeckillOrder> findAll() {
    return seckillOrderMapper.selectAll();
  }


}
